package viewset.com.kkcamera.view.image.opengl.filter.graph

import android.content.Context
import android.opengl.GLES20
import com.chan.mediacamera.camera.filter.BaseFilter
import com.chan.mediacamera.util.MatrixTools
import com.chan.mediacamera.util.OpenGlUtils
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.*

/**
 * 圆球fillter
 */
class BallFillter(var context: Context) : BaseFilter(context) {

    private var matrixTools: MatrixTools? = null
    private val step = 5f
    private var mVertexCount: Int = 4

    override fun onCreateShare() {
        mContext?.let {
            mVertexShader = OpenGlUtils.loadShareFromAssetsFile("graph/ball_shader_vertex.glsl", it.resources)
            mFragmentShader = OpenGlUtils.loadShareFromAssetsFile("graph/ball_shader_fragment.glsl", it.resources)
        }
        matrixTools = MatrixTools()
    }

    override fun initBuffer() {
        val dataPos: FloatArray = createBallPos()

        // 字节数
        var buffer: ByteBuffer = ByteBuffer.allocateDirect(dataPos.size * 4)
        buffer.order(ByteOrder.nativeOrder())
        mVerBuffer = buffer.asFloatBuffer()
        mVerBuffer.put(dataPos)
        mVerBuffer.position(0)

        //多少个点
        mVertexCount = dataPos.size / 3
    }


    override fun onSizeChanged(width: Int, height: Int) {
        GLES20.glViewport(0, 0, width, height)

        GLES20.glEnable(GLES20.GL_DEPTH_TEST)

        //计算宽高比
        val ratio = width.toFloat() / height

        //设置透视投影
        //Matrix.frustumM(mProjectMatrix, 0, -ratio, ratio, -1f, 1f, 3f, 17f)
        //设置相机位置
        //Matrix.setLookAtM(mViewMatrix, 0, 0f, -13.0f, -4.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
        //计算变换矩阵
        //Matrix.multiplyMM(mMVPMatrix, 0, mProjectMatrix, 0, mViewMatrix, 0)

        matrixTools?.run {
            //设置透视投影
            frustum(-ratio, ratio, -1f, 1f, 3f, 17f)
            //设置相机位置
            setCamera(0f, -13.0f, -4.0f, 0f, 0f, 0f, 0f, 1.0f, 0.0f)
            //计算变换矩阵
            matrix = finalMatrix
        }
    }

    override fun onDraw() {
        GLES20.glEnableVertexAttribArray(glPosition)
        GLES20.glVertexAttribPointer(glPosition, 2, GLES20.GL_FLOAT, false, 0, mVerBuffer)

        GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, mVertexCount)
        GLES20.glDisableVertexAttribArray(glPosition)
    }

    private fun createBallPos(): FloatArray {
        //球以(0,0,0)为中心，以R为半径，则球上任意一点的坐标为
        // ( R * cos(a) * sin(b),y0 = R * sin(a),R * cos(a) * cos(b))
        // 其中，a为圆心到点的线段与xz平面的夹角，b为圆心到点的线段在xz平面的投影与z轴的夹角
        val data = ArrayList<Float>()
        var r1: Float
        var r2: Float
        var h1: Float
        var h2: Float
        var sin: Float
        var cos: Float
        run {
            var i = -90f
            while (i < 90 + step) {
                r1 = kotlin.math.cos(i * Math.PI / 180.0).toFloat()
                r2 = kotlin.math.cos((i + step) * Math.PI / 180.0).toFloat()
                h1 = kotlin.math.sin(i * Math.PI / 180.0).toFloat()
                h2 = kotlin.math.sin((i + step) * Math.PI / 180.0).toFloat()
                // 固定纬度, 360 度旋转遍历一条纬线
                val step2 = step * 2
                var j = 0.0f
                while (j < 360.0f + step) {
                    cos = kotlin.math.cos(j * Math.PI / 180.0).toFloat()
                    sin = -kotlin.math.sin(j * Math.PI / 180.0).toFloat()
                    data.add(r2 * cos)
                    data.add(h2)
                    data.add(r2 * sin)
                    data.add(r1 * cos)
                    data.add(h1)
                    data.add(r1 * sin)
                    j += step2
                }
                i += step
            }
        }
        val f = FloatArray(data.size)
        for (i in f.indices) {
            f[i] = data[i]
        }
        return f
    }
}